﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;
using Microsoft.Xna.Framework.Net;
using Microsoft.Xna.Framework.Storage;
using Freeform;

namespace Space_in_Shaders
{
    public class Missile : SpaceShip
    {
        public Single Thrust { get; set; }
        public Single TurnTorque { get; set; }
        public Single TorqueFrac { get; set; }
        public SpaceObject Target { get; set; }
        // Parent is used to destruct missiles with no alive owner. can probably be done a different way that's cleaner but I can't think of it right now.
        public SpaceObject Parent { get; set; }

        public Missile(SpaceObject Target, SpaceObject Parent, Vector2 Position, Single Direction, Single Speed)
            : base(Target.SpaceWorld)
        {
            this.Target = Target;
            this.Parent = Parent;
            Game.LoadAnimation(this);
            Actor.Depth = 0.5f;

            SpatialProperties.Size = new Vector2(3, 7);
            SpatialProperties.Position = Position;
            SpatialProperties.Direction = Direction;

            NMot.ForceResistance = 0.965f;
            NMot.Velocity = Util.Vec2InDir(Direction) * Speed;
            NMot.TorqueResistance = 0.975f;

            Damage = 6;
            Health = 2;
            Thrust = 700f;
            TurnTorque = 20f;
            ExplosionIntensity = 4;
            IsThrusting = true;
            PuffSpacing = 200;
            PuffOffset = -3;

            // Setup collision properties for the spaceship.
            CollisionProperties.CollisionID = RadialCollision.CID_MISSILE;
            CollisionProperties.CollisionType = CollisionType.Active;
            CollisionProperties.SetCollisionMask(RadialCollision.CID_LASER, true);
            CollisionProperties.SetCollisionMask(RadialCollision.CID_MISSILE, true);
            CollisionProperties.SetCollisionMask(RadialCollision.CID_AISHIP, true);
            CollisionProperties.SetCollisionMask(RadialCollision.CID_PLAYERSHIP, true);

            Radial.Radius = 4;
        }

        public override void Update(GameTime time)
        {
            base.Update(time);

            // Kill the missile if target is already dead.
            if (Target == null || Target.IsDestroyed || Target.Disposed) Destroy();

            // Kill the missile if parent is already dead.
            if (Parent == null || Parent.IsDestroyed || Parent.Disposed) Destroy();

            Vector2 Disp = Target.SpatialProperties.Position - SpatialProperties.Position;

            // Begin SMART MISSILE LOGIC (Comment out this block to use old missile logic.)
            Vector2 OtherVel = (Target.SpatialProperties.MotionController as NMotion).Velocity;
            Vector2 RelV = OtherVel - NMot.Velocity;
            Single ETA = Disp.Length() / RelV.Length();
            Vector2 Prediction = Target.SpatialProperties.Position + OtherVel * ETA;
            Disp = Prediction - SpatialProperties.Position;
            // End SMART MISSILE LOGIC

            Single ReqAng = (Single)Math.Atan2(Disp.X, -Disp.Y);

            Single Diff = ReqAng - SpatialProperties.Direction;
            if (Diff > Math.PI)
                Diff -= MathHelper.TwoPi;
            if (Diff < -Math.PI)
                Diff += MathHelper.TwoPi;

            TorqueFrac = Diff > 0 ? (Single)Math.Sqrt(Diff / (Single)Math.PI) : -(Single)Math.Sqrt(-Diff / (Single)Math.PI);

            NMot.ApplyTorque(TurnTorque * TorqueFrac);
            NMot.ApplyForce(Util.Vec2InDir(SpatialProperties.Direction) * Thrust);
        }
    }
}
